home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 November / Macworld (1999-11).dmg / Updaters / WhiteCap 3.0.4 / WhiteCap Source.sit / WhiteCap Source / Common / Graphics / LineXX.cpp < prev    next >
Text File  |  1999-07-31  |  5KB  |  241 lines

  1.  
  2.  
  3. #if CLR_INTERP
  4. void PixPort::_Line( int sx, int sy, int ex, int ey, const RGBColor& inS, long dR, long dG, long dB ) {
  5. #else
  6. void PixPort::_Line( int sx, int sy, int ex, int ey, long color ) {
  7. #endif
  8.     long xDirection, rowOffset, error_term;
  9.     char* basePtr, *center;
  10.     long xmov, ymov, dx, dy, t, j, lw;
  11.     long penExtents;
  12.  
  13.     #if CLR_INTERP
  14.     long color, R, G, B;
  15.     R = inS.red;
  16.     G = inS.green;
  17.     B = inS.blue;
  18.     #endif
  19.  
  20.     // Modify the line width so that the actual width matches mLineWidth
  21.     lw = mLineWidth;    
  22.     if ( mLineWidth > 3 ) {
  23.         dx = ex - sx;    dx = dx * dx;
  24.         dy = ey - sy;    dy = dy * dy;
  25.         if ( dx > 0 && dx >= dy )
  26.             lw = 128 + 55 * dy / dx;             // 1/cos( atan( x ) ) is about 1+.43*x^2 from 0 to 1 (55 == .43 * 128)
  27.         else if ( dy > 0 && dy > dx )
  28.             lw = 128 + 55 * dx / dy;             // 1/cos( atan( x ) ) is about 1+.43*x^2 from 0 to 1 (55 == .43 * 128)
  29.         
  30.         if ( dx > 0 || dy > 0 )
  31.             lw = ( mLineWidth * lw + 64 ) >> 7;        // Add in order to round up
  32.     }
  33.     penExtents = lw >> 1;
  34.  
  35.     
  36.     
  37.     // Clipping: Set the pen loc to a point that's in and stop drawing once/if the pen moves out
  38.     if ( sx < penExtents || sx >= mX - penExtents || sy < penExtents || sy >= mY - penExtents ) {
  39.         t = ex; ex = sx; sx = t;
  40.         t = ey; ey = sy; sy = t;
  41.         
  42.         #if CLR_INTERP
  43.         R += dR; G += dG; B += dB;
  44.         dR = -dR; dG = -dG; dB = -dB;
  45.         #endif
  46.     }
  47.     
  48.     // Exit if the start pt is out of bounds (wimpy clipping, eh?)
  49.     if ( sx < penExtents || sx >= mX - penExtents || sy < penExtents || sy >= mY - penExtents )
  50.         return;
  51.     
  52.  
  53.     // In Win32, everything's upside down
  54.     #if EG_WIN
  55.     sy = mY - sy;
  56.     ey = mY - ey;
  57.     #endif    
  58.     
  59.     dx = ex - sx;
  60.     dy = ey - sy;
  61.     
  62.     
  63.     #if CLR_INTERP
  64.     long len = sqrt( dx * dx + dy * dy ) + 1;
  65.     dR /= len;
  66.     dG /= len;
  67.     dB /= len;
  68.     color = __Clr( R, G, B );
  69.     #endif
  70.         
  71.     
  72.     // moving left or right?
  73.     xmov = dx;
  74.     if ( dx < 0 ) {
  75.         xmov = -dx;
  76.         if ( sx - xmov < penExtents )
  77.             xmov = sx - penExtents;
  78.         xDirection = - P_SZ;
  79.         dx = -dx; }
  80.     else if ( dx > 0 ) {
  81.         if ( sx + xmov >= mX - penExtents )
  82.             xmov = mX - penExtents - 1 - sx;
  83.         xDirection = P_SZ;  }
  84.     else 
  85.         xDirection = 0;
  86.  
  87.     // moving up or down?
  88.     ymov = dy;
  89.     if ( dy < 0 ) {
  90.         ymov = -dy;
  91.         if ( sy - ymov < penExtents )
  92.             ymov = sy - penExtents;
  93.         rowOffset = - mBytesPerRow;
  94.         dy = -dy; }
  95.     else {
  96.         if ( sy + ymov >= mY - penExtents )
  97.             ymov = mY - penExtents - sy - 1;
  98.         rowOffset = mBytesPerRow; 
  99.     } 
  100.  
  101.     basePtr = mBits + sy * mBytesPerRow + sx * P_SZ;
  102.     error_term = 0;
  103.     
  104.     long halfW;
  105.  
  106.     if ( lw > 1 ) {
  107.     
  108.  
  109.         
  110.         
  111.         // Make a circle for the pen
  112.         long c_x, tw = mLineWidth;
  113.         halfW = ( tw ) >> 1;
  114.         
  115.         if ( tw < 12 ) {
  116.             char* c_shape;
  117.             __circ( tw, c_shape )
  118.             for ( j = 0; j < tw; j++ ) {
  119.                 long tmp = j - halfW;
  120.                 c_x = c_shape[ j ];
  121.                 center = basePtr + (j-halfW) * mBytesPerRow;
  122.                 for ( int k = c_x; k < tw - c_x; k++ ){
  123.                     ((PIXTYPE*) center)[k-halfW] = color;
  124.                 }
  125.             } }
  126.         else {        
  127.         
  128.             for ( j = 0; j < tw; j++ ) {
  129.                 long tmp = j - halfW;
  130.                 c_x = halfW - ( ( long ) sqrt( halfW * halfW - tmp * tmp ) );
  131.                 center = basePtr + (j-halfW) * mBytesPerRow;
  132.                 for ( int k = c_x; k < tw - c_x; k++ ){
  133.                     ((PIXTYPE*) center)[k-halfW] = color;
  134.                 }
  135.             }
  136.         }
  137.         
  138.         
  139.         halfW = lw >> 1;
  140.  
  141.         // Draw the line
  142.         if ( dx > dy ) {
  143.             
  144.             // Start counting off in x
  145.             for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
  146.  
  147.                 #if CLR_INTERP
  148.                 __calcClr
  149.                 #endif
  150.                 
  151.                 // Draw the vertical leading edge of the pen
  152.                 center = basePtr - halfW * mBytesPerRow;
  153.                 for ( j = 0; j < lw; j++ ) {
  154.                     *((PIXTYPE*) center) = color;
  155.                     center += mBytesPerRow;
  156.                 }
  157.                 /*
  158.                 // Draw the horizontal leading edge of the pen
  159.                 center = basePtr + halfW * ( rowOffset - P_SZ );
  160.                 for ( j = 0; j < lw; j++ ) {
  161.                     *((PIXTYPE*) center) = color;
  162.                     center += P_SZ;
  163.                 }*/
  164.                 basePtr += xDirection;
  165.  
  166.                 // Check to see if we need to move the pixelOffset in the y direction.
  167.                 __doXerr
  168.             } }
  169.         else {
  170.             // Start counting off in y
  171.             for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
  172.             
  173.                 #if CLR_INTERP
  174.                 __calcClr
  175.                 #endif
  176.                 /*
  177.                 // Draw the vertical leading edge of the pen
  178.                 center = basePtr + xDirection * (halfW) - P_SZ - halfW * mBytesPerRow;
  179.                 for ( j = 0; j < lw; j++ ) {
  180.                     *((PIXTYPE*) center) = color;
  181.                     center += mBytesPerRow;
  182.                 }*/
  183.                 // Draw the horizontal leading edge of the pen
  184.                 center = basePtr - ( halfW ) * P_SZ;
  185.                 for ( j = 0; j < lw; j++ ) {
  186.                     *((PIXTYPE*) center) = color;
  187.                     center += P_SZ;
  188.                 }
  189.                 basePtr += rowOffset;
  190.  
  191.                 // Check to see if we need to move the pixelOffset in the y direction.
  192.                 __doYerr
  193.             }
  194.         }
  195.         
  196.         // If line len is 0, we don't need to draw ending pen circle
  197.         /*
  198.         if ( lw > 3 ) {
  199.             if ( dx != 0 || dy != 0 ) {
  200.             }
  201.         } */
  202.  
  203.         }
  204.     else {
  205.     
  206.         // Draw the (single pixel) line
  207.         if ( dx >= dy ) {
  208.             
  209.             // Start counting off in x
  210.             for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
  211.             
  212.                 #if CLR_INTERP
  213.                 __calcClr
  214.                 #endif
  215.                 
  216.                 *((PIXTYPE*) basePtr) = color;
  217.                 
  218.                 basePtr += xDirection;
  219.  
  220.                 // Check to see if we need to move the pixelOffset in the y direction.
  221.                 __doXerr
  222.             } }
  223.         else {
  224.             // Start counting off in y
  225.             for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
  226.             
  227.                 #if CLR_INTERP
  228.                 __calcClr
  229.                 #endif
  230.                 
  231.                 *((PIXTYPE*) basePtr) = color;
  232.                 basePtr += rowOffset;
  233.  
  234.                 // Check to see if we need to move the pixelOffset in the y direction.
  235.                 __doYerr
  236.             }
  237.         }
  238.     }
  239.  
  240. }
  241.